package org.kungfu.generator.easyui;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import org.kungfu.core.Constants;
import org.kungfu.generator.TableMeta;

import com.jfinal.kit.StrKit;

/**
 * Model API 生成器
 */
public class ModelAPIGenerator {
	protected String packageTemplate =
			"package %s.%s;%n%n";
	protected String importTemplate =
			//"import com.jfinal.plugin.activerecord.Model;%n%n" +
			"import com.jfinal.plugin.activerecord.Page;%n%n" +
			"import %s.%s.%s;%n%n";
	protected String classDefineTemplate =
		"/**%n" +
		" * API, Generated by Robot on " + Constants.DATE_TIME + ".%n" +
		" */%n" +
		"public interface %sAPI {%n";
	
	protected String pageSampleTemplate =
			"%n\tPage<%s> page(int pageNumber, int pageSize);%n%n";
	
	protected String pageClauseTemplate =
			"\tPage<%s> page(int pageNumber, int pageSize, String orderField, String orderDirection, String where);%n%n";
	
	protected String saveOrUpdateTemplate =
			"\tboolean saveOrUpdate(%s model);%n%n";
	
	protected String findByIdTemplate =
			"\t%s findById(Object idValue);%n%n";
	
	protected String deleteTemplate =
			"\tboolean deleteById(Object idValue);%n%n";

	
	protected String modelPackageName;
	protected String baseModelPackageName;
	protected String modelOutputDir;
	protected boolean generateDaoInModel = true;
	
	public ModelAPIGenerator(String modelPackageName, String baseModelPackageName, String modelOutputDir) {
		if (StrKit.isBlank(modelPackageName))
			throw new IllegalArgumentException("modelPackageName can not be blank.");
		if (modelPackageName.contains("/") || modelPackageName.contains("\\"))
			throw new IllegalArgumentException("modelPackageName error : " + modelPackageName);
		if (StrKit.isBlank(baseModelPackageName))
			throw new IllegalArgumentException("baseModelPackageName can not be blank.");
		if (baseModelPackageName.contains("/") || baseModelPackageName.contains("\\"))
			throw new IllegalArgumentException("baseModelPackageName error : " + baseModelPackageName);
		if (StrKit.isBlank(modelOutputDir))
			throw new IllegalArgumentException("modelOutputDir can not be blank.");
		
		this.modelPackageName = modelPackageName;
		this.baseModelPackageName = baseModelPackageName;
		this.modelOutputDir = modelOutputDir;
	}
	
	public void setGenerateDaoInModel(boolean generateDaoInModel) {
		this.generateDaoInModel = generateDaoInModel;
	}
	
	public void generate(List<TableMeta> tableMetas) {
		System.out.println("Generate modelAPI ...");
		for (TableMeta tableMeta : tableMetas)
			genModelContent(tableMeta);
		wirtToFile(tableMetas);
	}
	
	protected void genModelContent(TableMeta tableMeta) {
		StringBuilder ret = new StringBuilder();
		genPackage(tableMeta, ret);
		genImport(tableMeta, ret);
		genInterfaceDefine(tableMeta, ret);
		genPageSampleMethodName(tableMeta, ret);
		genPageClauseMethodName(tableMeta, ret);
		genSaveOrUpdateMethodName(tableMeta, ret);
		genFindByIdMethodName(tableMeta, ret);
		genDeleteMethodName(ret);
		ret.append(String.format("}%n"));
		tableMeta.modelContent = ret.toString();
	}
	
	protected void genPackage(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(packageTemplate, modelPackageName, tableMeta.modelName.toLowerCase().replaceAll("_", "")));
	}
	
	protected void genImport(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(importTemplate, modelPackageName, tableMeta.modelName.toLowerCase().replaceAll("_", ""), tableMeta.modelName));
	}
	
	protected void genInterfaceDefine(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(classDefineTemplate, tableMeta.modelName));
	}
	
	protected void genPageSampleMethodName(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(pageSampleTemplate, tableMeta.modelName));
	}
	
	protected void genPageClauseMethodName(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(pageClauseTemplate, tableMeta.modelName));
	}
	
	protected void genSaveOrUpdateMethodName(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(saveOrUpdateTemplate, StrKit.firstCharToUpperCase(tableMeta.modelName)));
	}
	
	protected void genFindByIdMethodName(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(findByIdTemplate, tableMeta.modelName));
	}
	
	protected void genDeleteMethodName(StringBuilder ret) {
		ret.append(String.format(deleteTemplate));
	}
	
	
	protected void wirtToFile(List<TableMeta> tableMetas) {
		try {
			for (TableMeta tableMeta : tableMetas)
				wirtToFile(tableMeta);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 若 model 文件存在，则不生成，以免覆盖用户手写的代码
	 */
	protected void wirtToFile(TableMeta tableMeta) throws IOException {
		File dir = new File(modelOutputDir + File.separator + tableMeta.modelName.toLowerCase().replaceAll("_", "") );
		if (!dir.exists())
			dir.mkdirs();
		
		String target = modelOutputDir + File.separator + tableMeta.modelName.toLowerCase().replaceAll("_", "") + File.separator + tableMeta.modelName + "API.java";
		
		File file = new File(target);
		if (file.exists()) {
			return ;	// 若 Model 存在，不覆盖
		}
		
		FileWriter fw = new FileWriter(file);
		try {
			fw.write(tableMeta.modelContent);
		}
		finally {
			fw.close();
		}
	}
}


